package com.mingqijia.gassafety.job.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gap.basic.exception.BizException;
import com.gap.cache.redis.RedisCache;
import com.mingqijia.gassafety.db.entity.Consumer;
import com.mingqijia.gassafety.db.entity.ConsumerServiceInfo;
import com.mingqijia.gassafety.db.entity.Dtu;
import com.mingqijia.gassafety.db.entity.InformRecord;
import com.mingqijia.gassafety.db.entity.RunningStrategyExt;
import com.mingqijia.gassafety.db.entity.WarnStrategy;
import com.mingqijia.gassafety.db.entity.WarnStrategyExt;
import com.mingqijia.gassafety.db.entity.vo.SendMessagePhonesVo;
import com.mingqijia.gassafety.db.mapper.BusinessNoticeMapper;
import com.mingqijia.gassafety.db.mapper.ConsumerMapper;
import com.mingqijia.gassafety.db.mapper.ContactsMapper;
import com.mingqijia.gassafety.db.mapper.CustomerSubsMapper;
import com.mingqijia.gassafety.db.mapper.DeviceStateMapper;
import com.mingqijia.gassafety.db.mapper.DictionaryMapper;
import com.mingqijia.gassafety.db.mapper.DtuBindingOrderMapper;
import com.mingqijia.gassafety.db.mapper.DtuMapper;
import com.mingqijia.gassafety.db.mapper.InformRecordMapper;
import com.mingqijia.gassafety.db.mapper.ReceiverValveMapper;
import com.mingqijia.gassafety.db.mapper.RecordReceiverValveMapper;
import com.mingqijia.gassafety.db.mapper.RunningRecordMapper;
import com.mingqijia.gassafety.db.mapper.RunningStrategyExtMapper;
import com.mingqijia.gassafety.db.mapper.RunningStrategyMapper;
import com.mingqijia.gassafety.job.dto.CallTaskDTO;
import com.mingqijia.gassafety.job.dto.PredateStrategyDTO;
import com.mingqijia.gassafety.job.dto.SendMessageDTO;
import com.mingqijia.gassafety.job.response.VccUserRseponse;
import com.mingqijia.gassafety.job.service.AicallTaskService;
import com.mingqijia.gassafety.job.service.ConsumerService;
import com.mingqijia.gassafety.job.strategy.RecordService;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.DtuPushTypeEnum;
import com.mingqijia.gassafety.shared.constant.EquipmentTypeConst;
import com.mingqijia.gassafety.shared.constant.MessagePushTypeEnum;
import com.mingqijia.gassafety.shared.constant.PushServicePeriodLevelEnum;
import com.mingqijia.gassafety.shared.constant.SMSTypeEnum;
import com.mingqijia.gassafety.shared.constant.StrategyTypeEnum;
import com.mingqijia.gassafety.shared.constant.WxTypeEnum;
import com.mingqijia.gassafety.shared.constant.warnStrategy.NotifyObjTypeTypeEnum;
import com.mingqijia.gassafety.shared.constant.warnStrategy.WarnStrategyIntervalEnum;
import com.mingqijia.gassafety.shared.constant.warnStrategy.WarnStrategyTypeEnum;
import com.mingqijia.gassafety.shared.dto.AssembleTemplateDTO;
import com.mingqijia.gassafety.shared.utils.RedisCacheExt;
import com.mingqijia.gassafety.shared.utils.commonUtils.DateUtils;
import com.mingqijia.gassafety.shared.utils.message.SendMessageService;
import com.mingqijia.gassafety.shared.vcc.VccAuthoritiesProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * @author mby
 * @version 1.0.0
 * @ClassName ServicePeriodStrategyServiceImpl.java
 * @Description
 * @createTime 2024年01月25日
 */

@Component
@Slf4j
public class WarnStrategyV2ServiceImpl {

    @Autowired
    RedisCache redisCache;
    @Autowired
    ConsumerMapper consumerMapper;
    @Autowired
    CustomerSubsMapper customerSubsMapper;
    @Autowired
    DtuMapper dtuMapper;
    @Autowired
    RunningStrategyExtMapper extMapper;
    @Autowired
    ContactsMapper contactsMapper;
    @Autowired
    SendMessageService sendMessageService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    DictionaryMapper dictionaryMapper;
    @Autowired
    RunningStrategyMapper warnStrategyMapper;

    @Autowired
    EquipmentServiceImpl equipmentService;
    @Autowired
    CompanyServiceImpl companyService;

    @Autowired
    DevicebindingServiceImpl devicebindingService;
    @Autowired
    BusinessNoticeMapper noticeMapper;

    @Autowired
    InformRecordMapper informRecordMapper;
    @Autowired
    RunningRecordMapper runningRecordMapper;
    @Autowired
    ReceiverValveMapper receiverValveMapper;

    @Autowired
    XFCallServiceImpl xFCallService;

    @Autowired
    AicallTaskService aicallTaskService;

    @Value(value = "${gassafety.warnStrategy.switch}")
    private boolean sw;
    @Autowired
    RedisCacheExt redisUtil;

    @Autowired
    VccAuthoritiesProvider provider;

    @Autowired
    DeviceStateMapper deviceStateMapper;
    @Autowired
    DtuBindingOrderMapper dtuBindingOrderMapper;
    @Autowired
    ConsumerService consumerService;
    @Autowired
    CallTaskServiceImpl callTaskService;
    @Autowired
    RecordReceiverValveMapper recordReceiverValveMapper;


    @Resource
    WarningRecordServiceImpl warningRecordService;

    // 两分半
    private final Integer offsetRangeConstant = 150000;
    // 十分钟
    private final Integer MaxRangeConstant = 600000;

    /**
     * 判断是否满足发送频率
     * @param messagePushTypeEnum 消息发送方式
     * @param cacheMap 缓存
     * @param sendInterval  发送间隔
     * @param nextSendTime 下一次发送时间
     * @param predateStrategyDTO 信息发送判断，组装数据策略所需的数据
     */
    public boolean checkSendRun(MessagePushTypeEnum messagePushTypeEnum, Map<String, Object> cacheMap, Long sendInterval, Object nextSendTime, PredateStrategyDTO predateStrategyDTO) {
        // 该步骤必读有推送频率能正常推送
        if (nextSendTime == null) {
            // 第一次发送可以不用判断频率
            log.info("swarnStrategyAgain-predicateGasLowWarn-第一次发送,pushType：{},imei：{}", messagePushTypeEnum.getName(), predateStrategyDTO.getImei());
        } else {
            Long nextSendTimeStamp = (Long)nextSendTime;
            log.info("warnStrategyAgain-predicateGasLowWarn-发送频率校验，pushType：{}，sendInterval:{}, nowTime：{}，nextSendTime：{}，diffTime：{}",  messagePushTypeEnum.getName(), sendInterval, predateStrategyDTO.getNowTime(), nextSendTimeStamp, predateStrategyDTO.getNowTime() - nextSendTimeStamp);
            //超过10分钟没有发送，清除
            if (predateStrategyDTO.getNowTime() - nextSendTimeStamp >= 600000) {
                log.info("warnStrategyAgain-predicateGasLowWarn-超时删除，imei：{}", predateStrategyDTO.getImei());
                deleteCache(predateStrategyDTO, cacheMap.get("identificationCode").toString());
                return false;
            }
            //        if (!(nextSendTime != null && time - nextSendTime <= offsetRangeConstant
//                && time - nextSendTime >= 0)) return true;
            if (predateStrategyDTO.getNowTime() - nextSendTimeStamp < 0) {
                log.info("warnStrategyAgain-predicateGasLowWarn-当前时间不满足发送频率");
                return false;
            }
        }


        return true;
    }

    /**
     * 判断是否满足发送频率
     * @param imei imei
     * @param count 本次发送是第几次
     * @param warnStrategyTypeEnum 燃气泄露报警策略类型
     * @param messagePushTypeEnum 消息推送方式
     * @param warnStrategyExtList 策略明细列表
     */
    public WarnStrategyExt getWarnStrategyExt(String imei, Integer count, WarnStrategyTypeEnum warnStrategyTypeEnum, MessagePushTypeEnum messagePushTypeEnum, List<WarnStrategyExt> warnStrategyExtList) {
        // pushType 短信1 外呼2
        List<WarnStrategyExt> newWarnStrategyExtList = warnStrategyExtList.stream().filter(x -> x.getType() == warnStrategyTypeEnum.getCode()
                && x.getPushType() == (messagePushTypeEnum.getGasWarnCode() == MessagePushTypeEnum.SMS.getGasWarnCode() ? 1 : 2)
                && x.getReportNumberStart() <= count
                && x.getReportNumberEnd() >= count).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(newWarnStrategyExtList)) {
            // 本次不发
            log.info("swarnStrategyAgain-predicateGasLowWarn-本次发送无对应配置-pushType：{}，count:{},imei：{}", messagePushTypeEnum.getName(), count, imei);
            return null;
        } else {
            return newWarnStrategyExtList.get(0);
        }
    }

    /**
     * 组装数据
     * @param warnStrategy 策略信息
     * @param warnStrategyExt  策略明细信息
     * @param messagePushTypeEnum 消息推送方式
     * @param cacheMap 缓存
     * @param dto 组装的发送数据
     * @param predateStrategyDTO 信息发送判断，组装数据策略所需的数据
     */
    public void predicateGasWarn(WarnStrategy warnStrategy, WarnStrategyExt warnStrategyExt, MessagePushTypeEnum messagePushTypeEnum,
                                 Map<String, Object> cacheMap, SendMessageDTO dto, PredateStrategyDTO predateStrategyDTO) {

        dto.setConsumerId(predateStrategyDTO.getConsumer().getId());
        dto.setConsumerPhone(predateStrategyDTO.getConsumer().getPhone());
        dto.setMemberId(predateStrategyDTO.getConsumer().getMemberId());
        dto.setCustName(predateStrategyDTO.getConsumer().getCustName());
        dto.setSubsCode(predateStrategyDTO.getConsumer().getSubsCode());
        dto.setAddress(predateStrategyDTO.getConsumer().getCustAddress());
        dto.setPkgId(predateStrategyDTO.getConsumer().getPkgId());
        dto.setSpId(warnStrategy.getSpId());
        dto.setConsumerName(predateStrategyDTO.getConsumer().getName());

        dto.setSuperImei(predateStrategyDTO.getSuperImei());
        dto.setImei(predateStrategyDTO.getImei());
        dto.setValue(predateStrategyDTO.getValue());
        dto.setPosition(predateStrategyDTO.getDtu().getInstallationPosition());
        dto.setEquipmentType(predateStrategyDTO.getDtu().getEquipmentType());
        dto.setEquipmentFrom(predateStrategyDTO.getDtu().getEquipmentFrom());

        dto.setKey(predateStrategyDTO.getKey());
        dto.setStrategyId(warnStrategy.getId());
        dto.setType((Integer)cacheMap.get("type"));
        dto.setPushType(messagePushTypeEnum.getGasWarnCode());
        dto.setPushTypeCode(messagePushTypeEnum.getValue());
        dto.setSnowflakeId(predateStrategyDTO.getSnowflakeId());

        // 推送人
        List<SendMessagePhonesVo> phones = new ArrayList<>();
        // 微信设置的推送联系人
        if (StringUtils.isNotBlank(predateStrategyDTO.getWxPhones())) {
            for (String phone : predateStrategyDTO.getWxPhones().split(";")) {
                if (StringUtils.isNotBlank(phone)) {
                    SendMessagePhonesVo vo = new SendMessagePhonesVo();
                    vo.setNotifyObjType(NotifyObjTypeTypeEnum.EXTRA.getCode());
                    vo.setTelephone(phone);
                    phones.add(vo);
                }
            }
        }

        // 短信和机器人外呼设置的报警次数
        if (warnStrategyExt != null) {
            // 推送客户联系人
            if (warnStrategyExt.getPushLevel() != null && warnStrategyExt.getPushLevel() != 0 && warnStrategyExt.getPushLevel() != 99){
                List<SendMessagePhonesVo> contractPhoneList= contactsMapper.selectServicePeriodPhones(predateStrategyDTO.getConsumer().getId(), Arrays.asList(warnStrategyExt.getPushLevel().toString()));
                // 通知对象 客户
                for (SendMessagePhonesVo phoneVo : contractPhoneList) {
                    phoneVo.setNotifyObjType(NotifyObjTypeTypeEnum.CONSUMER.getCode());
                }
                if (CollectionUtils.isNotEmpty(contractPhoneList)) {
                    phones.addAll(contractPhoneList);
                }
            }
            // 推送企业员工
            if (StringUtils.isNotBlank(warnStrategyExt.getPushStaffs())){
                // 通知对象 企业员工
                for (String phone : warnStrategyExt.getPushStaffs().split(";")) {
                    if (StringUtils.isNotBlank(phone)) {
                        SendMessagePhonesVo vo = new SendMessagePhonesVo();
                        vo.setNotifyObjType(NotifyObjTypeTypeEnum.CONSUMER.getCode());
                        vo.setTelephone(phone);
                        phones.add(vo);
                    }
                }
            }

            // 推送额外手机号码  callPhones包含sendPhones
            if (StringUtils.isNotBlank(warnStrategyExt.getCallPhones())){
                // 通知对象 额外联系人
                for (String phone : warnStrategyExt.getCallPhones().split(";")) {
                    if (StringUtils.isNotBlank(phone)) {
                        SendMessagePhonesVo vo = new SendMessagePhonesVo();
                        vo.setNotifyObjType(NotifyObjTypeTypeEnum.EXTRA.getCode());
                        vo.setTelephone(phone);
                        phones.add(vo);
                    }
                }
            }
        }
        dto.setPhones(phones);
        String orgCode = companyService.getOrgCode(dto.getSpId(), String.valueOf(dto.getConsumerId()));
        dto.setOrgCode(orgCode);
        dto.setOrgName(predateStrategyDTO.getOrgName());
        dto.setOrgPhone(predateStrategyDTO.getOrgPhone());

        String factoryName = equipmentService.getEquipmentManufacturerName(predateStrategyDTO.getDtu().getEquipmentManufacturer(),dto.getSpId());
        dto.setFactoryName(factoryName);


        // 微信绑定用户
        if (messagePushTypeEnum == MessagePushTypeEnum.WX && StringUtils.isNotEmpty(dto.getSubsCode())
                && StringUtils.isNotEmpty(dto.getOrgCode())) {
            log.info("warnStrategyAgain-getVccUser：subsCode：{},orgCode：{}", dto.getSubsCode(),dto.getOrgCode());
            VccUserRseponse vccUser = consumerService.getVccUser(dto.getSubsCode(), "", dto.getOrgCode());
            if (vccUser ==null ){
                log.info("warnStrategyAgain-getVccUser：vcc不存在");
            } else {
                log.info("warnStrategyAgain-getVccUser：{}", vccUser);
                dto.setPhone(vccUser.getCustPhone());
            }
        }

    }

    public void setParams(MessagePushTypeEnum pushType, PredateStrategyDTO predateStrategyDTO, SendMessageDTO dto) {
        Map<String, Object> param = new HashMap<>();
        param.put("Time", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        param.put("value", dto.getValue() +"%LEL");
        param.put("position",  org.springframework.util.StringUtils.isEmpty(dto.getPosition()) ? Constants.BLANK : dto.getPosition());
        param.put("Equipmenttype", EquipmentTypeConst.equipmentTypeMaps.get(dto.getEquipmentType()));
        param.put("IMEI", dto.getSuperImei());  // 主的IMEI
        param.put("Equipment_status", "报警");
        param.put("phone", StringUtils.isEmpty(dto.getConsumerPhone()) ? Constants.BLANK : dto.getConsumerPhone());
        param.put("UserID", StringUtils.isEmpty(dto.getMemberId()) ? Constants.BLANK : dto.getMemberId());
        param.put("Name", StringUtils.isEmpty(dto.getCustName()) ? Constants.BLANK : dto.getCustName());
        param.put("address", StringUtils.isEmpty(dto.getAddress()) ? Constants.BLANK : dto.getAddress()); // 联系人地址
        if (pushType == MessagePushTypeEnum.WX && param.get("address").toString().length() > 20) {
            param.put("address", param.get("address").toString().substring(0, 20)); // 联系人地址
        }
        param.put("EquipmentName", StringUtils.isEmpty(predateStrategyDTO.getDtu().getName()) ? Constants.BLANK : StringUtils.isEmpty(predateStrategyDTO.getDtu().getName()));
        param.put("subsName", StringUtils.isEmpty(dto.getCustName()) ? (StringUtils.isEmpty(predateStrategyDTO.getConsumer().getName()) ? Constants.BLANK : predateStrategyDTO.getConsumer().getName()) : dto.getCustName());
        param.put("subsCode",  StringUtils.isEmpty(dto.getSubsCode()) ? Constants.BLANK : dto.getSubsCode());
        if (pushType == MessagePushTypeEnum.WX &&
            param.get("subsName").toString().length() > 18 - param.get("subsCode").toString().length()) {
            param.put("subsName", param.get("subsName").toString().substring(0, 15 - param.get("subsCode").toString().length()) + "..."); // 联系人地址
        }
        param.put("factoryName", StringUtils.isEmpty(dto.getFactoryName()) ? Constants.BLANK : dto.getFactoryName());
        param.put("ConsumerName", dto.getConsumerName());
        dto.setParam(param);
    }

    /**
     * 判断是否发送本地消息，如果是，组装发送信息
     * @param warnStrategyTypeEnum 报警类型  低报，高报
     * @param warnStrategy 报警策略
     * @param cacheMap  燃气泄漏报警缓存
     * @param sendDataList  组装的发送数据列表
     * @param predateStrategyDTO 执行策略所需的数据
     */
    public void predicateSendLocal(WarnStrategyTypeEnum warnStrategyTypeEnum, WarnStrategy warnStrategy, Map<String, Object> cacheMap,
        List<SendMessageDTO> sendDataList, PredateStrategyDTO predateStrategyDTO) {
        // 获取推送频率
        WarnStrategyIntervalEnum warnStrategyIntervalEnum = WarnStrategyIntervalEnum.matcher(warnStrategyTypeEnum == WarnStrategyTypeEnum.LOW ?
            warnStrategy.getLowReportInterval() : warnStrategy.getHighReportInterval());
        if (ObjectUtils.isEmpty(warnStrategyIntervalEnum)) {
            throw new BizException("warnStrategyAgain-sendLocal-无推送频率!");
        }
        // 根据推送频率判断本次是否应该发送
        Object nextSendTime = cacheMap.get("nextReportTime");
        if (!checkSendRun(MessagePushTypeEnum.LOCAL, cacheMap, warnStrategyIntervalEnum.getInterval(), nextSendTime, predateStrategyDTO)) {
            throw new BizException("warnStrategyAgain-sendLocal-推送频率不满足!");
        }

        // 填写下一次本地消息发送的时间
        long nextSend = DateUtil.offsetMinute(predateStrategyDTO.getDate(), warnStrategyIntervalEnum.getMinute()).getTime();
        cacheMap.put("nextReportTime", nextSend);
        // 判断本地是第几次发送
        Integer count = 0;
        if (cacheMap.get("count_r") == null) {
            // 第一次
            count = 1;
        } else {
            count = (Integer)cacheMap.get("count_r") + 1;
        }
        cacheMap.put("count_r", count);
        // 组装数据
        SendMessageDTO dto = new SendMessageDTO();
        predicateGasWarn(warnStrategy, null, MessagePushTypeEnum.LOCAL, cacheMap, dto, predateStrategyDTO);
        String localMessage = Constants.WARNING_LOCAL_MESSAGES.replace("type", warnStrategyTypeEnum.getValue())
            .replace("time", DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm:ss"))
            .replace("name",  predateStrategyDTO.getConsumer() == null ? Constants.BLANK : (StringUtils.isEmpty(predateStrategyDTO.getConsumer().getName()) ? Constants.BLANK : predateStrategyDTO.getConsumer().getName()))
            .replace("num", dto.getSuperImei()) // 主的IMEI
            .replace("value", dto.getValue().toString());
        dto.setContent(localMessage);
        sendDataList.add(dto);
    }

    /**
     * 判断是否发送短信，如果是，组装发送信息
     * @param warnStrategyTypeEnum 报警类型  低报，高报
     * @param warnStrategy 报警策略
     * @param warnStrategyExtList 策略明细列表
     * @param cacheMap  燃气泄漏报警缓存
     * @param sendDataList  组装的发送数据列表
     * @param predateStrategyDTO 执行策略所需的数据
     */
    public void predicateSendSms(WarnStrategyTypeEnum warnStrategyTypeEnum, WarnStrategy warnStrategy, List<WarnStrategyExt> warnStrategyExtList, Map<String, Object> cacheMap,
        List<SendMessageDTO> sendDataList, PredateStrategyDTO predateStrategyDTO) {
        // 获取推送频率
        WarnStrategyIntervalEnum warnStrategyIntervalEnum = WarnStrategyIntervalEnum.matcher(warnStrategyTypeEnum == WarnStrategyTypeEnum.LOW ?
            warnStrategy.getLowSendInterval() : warnStrategy.getHighSendInterval());
        if (ObjectUtils.isEmpty(warnStrategyIntervalEnum)) {
            throw new BizException("warnStrategyAgain-sendSms-无推送频率!");
        }
        // 根据推送频率判断本次是否应该发送
        Object nextSendTime = cacheMap.get("nextSendTime");
        if (!checkSendRun(MessagePushTypeEnum.SMS, cacheMap, warnStrategyIntervalEnum.getInterval(), nextSendTime, predateStrategyDTO)) {
            throw new BizException("warnStrategyAgain-sendSms-推送频率不满足!");
        }

        // 填写下一次短信消息发送的时间
        long nextSend = DateUtil.offsetMinute(predateStrategyDTO.getDate(), warnStrategyIntervalEnum.getMinute()).getTime();
        cacheMap.put("nextSendTime", nextSend);
        // 判断本地是第几次发送
        Integer count = 0;
        if (cacheMap.get("count_m") == null) {
            // 第一次
            count = 1;
        } else {
            count = (Integer)cacheMap.get("count_m") + 1;
        }
        if (count > 50) {
            throw new BizException("warnStrategyAgain-sendSms-短信推送超过50次，无策略明细!");
        }
        // 筛选出获取符合当前次数的策略明细
        WarnStrategyExt ext = getWarnStrategyExt(predateStrategyDTO.getImei(), count, warnStrategyTypeEnum, MessagePushTypeEnum.SMS, warnStrategyExtList);
        if (ObjectUtils.isEmpty(ext)) {
            log.info("warnStrategyAgain-sendSms-无策略明细!");
        } else {
            // 组装数据
            SendMessageDTO dto = new SendMessageDTO();
            predicateGasWarn(warnStrategy, ext, MessagePushTypeEnum.SMS, cacheMap, dto, predateStrategyDTO);
            setParams(MessagePushTypeEnum.SMS, predateStrategyDTO, dto); //组装短信发送需要的Param
            // 组装短信发送内容
            AssembleTemplateDTO assembleTemplate = new AssembleTemplateDTO();
            assembleTemplate.setSpId(dto.getSpId());
            assembleTemplate.setOrgCode(dto.getOrgCode());
            dto.setSendCode(Constants.WARN_STRATEGY);
            if (null!=cacheMap.get("smsMsgCode") && !ObjectUtils.isEmpty(cacheMap.get("smsMsgCode"))){
                dto.setSendCode(cacheMap.get("smsMsgCode").toString());
            }
            dto.setContent(sendMessageService.getSmsContent(dto.getSendCode(), dto.getParam(), assembleTemplate));
            sendDataList.add(dto);
        }
        cacheMap.put("count_m", count);
    }

    /**
     * 判断是否发送微信消息，如果是，组装发送信息
     * @param warnStrategyTypeEnum 报警类型  低报，高报
     * @param warnStrategy 报警策略
     * @param cacheMap  燃气泄漏报警缓存
     * @param sendDataList  组装的发送数据列表
     * @param predateStrategyDTO 执行策略所需的数据
     */
    public void predicateSendWx(WarnStrategyTypeEnum warnStrategyTypeEnum, WarnStrategy warnStrategy, Map<String, Object> cacheMap,
        List<SendMessageDTO> sendDataList, PredateStrategyDTO predateStrategyDTO) {
        // 获取推送频率
        WarnStrategyIntervalEnum warnStrategyIntervalEnum = WarnStrategyIntervalEnum.matcher(warnStrategyTypeEnum == WarnStrategyTypeEnum.LOW ?
            warnStrategy.getLowWxInterval() : warnStrategy.getHighWxInterval());
        if (ObjectUtils.isEmpty(warnStrategyIntervalEnum)) {
            throw new BizException("warnStrategyAgain-sendWx-无推送频率!");
        }
        // 根据推送频率判断本次是否应该发送
        Object nextSendTime = cacheMap.get("nextWxTime");
        if (!checkSendRun(MessagePushTypeEnum.WX, cacheMap, warnStrategyIntervalEnum.getInterval(), nextSendTime, predateStrategyDTO)) {
            throw new BizException("warnStrategyAgain-sendWx-推送频率不满足!");
        }

        // 填写下一次微信消息发送的时间
        long nextSend = DateUtil.offsetMinute(predateStrategyDTO.getDate(), warnStrategyIntervalEnum.getMinute()).getTime();
        cacheMap.put("nextWxTime", nextSend);
        // 判断本次是第几次发送
        Integer count = 0;
        if (cacheMap.get("count_w") == null) {
            // 第一次
            count = 1;
        } else {
            count = (Integer)cacheMap.get("count_w") + 1;
        }
        cacheMap.put("count_w", count);
        // 组装数据
        predateStrategyDTO.setWxPhones(warnStrategy.getLowWxPhones());
        SendMessageDTO dto = new SendMessageDTO();
        predicateGasWarn(warnStrategy, null, MessagePushTypeEnum.WX, cacheMap, dto, predateStrategyDTO);
        setParams(MessagePushTypeEnum.WX, predateStrategyDTO, dto); //组装短信发送需要的Param
        // 组装微信发送内容
        AssembleTemplateDTO assembleTemplate = new AssembleTemplateDTO();
        assembleTemplate.setSpId(dto.getSpId());
        assembleTemplate.setOrgCode(dto.getOrgCode());
        dto.setSendCode(Constants.WARN__WX_STRATEGY);
        if (null!=cacheMap.get("wxMsgCode") && !ObjectUtils.isEmpty(cacheMap.get("wxMsgCode"))){
            dto.setSendCode(cacheMap.get("wxMsgCode").toString());
        }
        dto.setContent(sendMessageService.getWxContent(dto.getSendCode(), dto.getParam(), assembleTemplate));
        sendDataList.add(dto);
    }

    /**
     * 判断是否发送短信，如果是，组装发送信息
     * @param warnStrategyTypeEnum 报警类型  低报，高报
     * @param warnStrategy 报警策略
     * @param warnStrategyExtList 策略明细列表
     * @param cacheMap  燃气泄漏报警缓存
     * @param sendDataList  组装的发送数据列表
     * @param predateStrategyDTO 执行策略所需的数据
     */
    public void predicateSendCall(WarnStrategyTypeEnum warnStrategyTypeEnum, WarnStrategy warnStrategy, List<WarnStrategyExt> warnStrategyExtList, Map<String, Object> cacheMap,
        List<SendMessageDTO> sendDataList, PredateStrategyDTO predateStrategyDTO) {
        // 获取推送频率
        WarnStrategyIntervalEnum warnStrategyIntervalEnum = WarnStrategyIntervalEnum.matcher(warnStrategyTypeEnum == WarnStrategyTypeEnum.LOW ?
            warnStrategy.getLowCallInterval() : warnStrategy.getHighCallInterval());
        if (ObjectUtils.isEmpty(warnStrategyIntervalEnum)) {
            throw new BizException("warnStrategyAgain-sendCall-无推送频率!");
        }
        // 根据推送频率判断本次是否应该发送
        Object nextSendTime = cacheMap.get("nextCallTime");
        if (!checkSendRun(MessagePushTypeEnum.CALL, cacheMap, warnStrategyIntervalEnum.getInterval(), nextSendTime, predateStrategyDTO)) {
            throw new BizException("warnStrategyAgain-sendCall-推送频率不满足!");
        }

        // 填写下一次机器人外呼发送的时间
        long nextSend = DateUtil.offsetMinute(predateStrategyDTO.getDate(), warnStrategyIntervalEnum.getMinute()).getTime();
        cacheMap.put("nextCallTime", nextSend);
        // 判断本次是第几次发送
        Integer count = 1;
        if (cacheMap.get("count_c") == null) {
            // 第一次
            count = 1;
        } else {
            count = (Integer)cacheMap.get("count_c") + 1;
        }
        if (count > 50) {
            throw new BizException("warnStrategyAgain-sendCall-外呼推送超过50次，无策略明细!");
        }
        // 筛选出获取符合当前次数的策略明细
        WarnStrategyExt ext = getWarnStrategyExt(predateStrategyDTO.getImei(), count, warnStrategyTypeEnum, MessagePushTypeEnum.CALL, warnStrategyExtList);
        if (ObjectUtils.isEmpty(ext)) {
            log.info("warnStrategyAgain-sendCall-无策略明细!");
        } else {
            // 组装数据
            SendMessageDTO dto = new SendMessageDTO();
            predateStrategyDTO.setWxPhones(Constants.BLANK);
            predicateGasWarn(warnStrategy, ext, MessagePushTypeEnum.CALL, cacheMap, dto, predateStrategyDTO);
            String message = Constants.WARNING_CALL_MESSAGES
                .replace("#name#", dto.getOrgName() == null ? Constants.BLANK : dto.getOrgName())
                .replace("#address#", dto.getPosition() == null ? Constants.BLANK : dto.getPosition())
                .replace("#phone#", dto.getOrgPhone() == null ? Constants.BLANK : dto.getOrgPhone())
                .replace("#factoryName#", dto.getFactoryName() == null ? Constants.BLANK : dto.getFactoryName());
            dto.setContent(message);
            sendDataList.add(dto);
        }
        cacheMap.put("count_c", count);
    }

    public void deleteCache(PredateStrategyDTO predateStrategyDTO, String identificationCode) {
        predateStrategyDTO.setSaveCache(false);
        redisCache.deleteObject(predateStrategyDTO.getKey());
        log.info("warnStrategyAgain-删除队列中的key：{}", predateStrategyDTO.getKey());
        //更新数据
        warningRecordService.updateRecordStatus(predateStrategyDTO.getImei(), identificationCode, 2);
        //删除策略执行次数key
        redisCache.deleteObject(Constants.ALARM_STRATEGY + predateStrategyDTO.getAlarmStrategykey());
        log.info("warnStrategyAgain-删除队列中的策略计数key：{}", "alarm_strategy" + predateStrategyDTO.getAlarmStrategykey());
    }


}